use std::fmt;

use serde::{Deserialize, Serialize};
use sqlx::types::Json;

#[derive(Debug, Deserialize, Serialize)]
pub enum TaskStatus {
    DataPending,
    DataRunning,
    DataCompleted,
    DataFailed,
    DataCanceled,
    ModelReconstructionPending,
    ModelReconstructionRunning,
    ModelReconstructionCompleted,
    ModelReconstructionFailed,
    ModelReconstructionCanceled,
    ModelDisposePending,
    ModelDisposeRunning,
    ModelDisposeCompleted,
    ModelDisposeFailed,
    ModelDisposeCanceled,
}

impl fmt::Display for TaskStatus {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            TaskStatus::DataPending => write!(f, "DataPending"),
            TaskStatus::DataRunning => write!(f, "DataRunning"),
            TaskStatus::DataCompleted => write!(f, "DataCompleted"),
            TaskStatus::DataFailed => write!(f, "DataFailed"),
            TaskStatus::DataCanceled => write!(f, "DataCanceled"),
            TaskStatus::ModelReconstructionPending => write!(f, "ModelReconstructionPending"),
            TaskStatus::ModelReconstructionRunning => write!(f, "ModelReconstructionRunning"),
            TaskStatus::ModelReconstructionCompleted => write!(f, "ModelReconstructionCompleted"),
            TaskStatus::ModelReconstructionFailed => write!(f, "ModelReconstructionFailed"),
            TaskStatus::ModelReconstructionCanceled => write!(f, "ModelReconstructionCanceled"),
            TaskStatus::ModelDisposePending => write!(f, "ModelDisposePending"),
            TaskStatus::ModelDisposeRunning => write!(f, "ModelDisposeRunning"),
            TaskStatus::ModelDisposeCompleted => write!(f, "ModelDisposeCompleted"),
            TaskStatus::ModelDisposeFailed => write!(f, "ModelDisposeFailed"),
            TaskStatus::ModelDisposeCanceled => write!(f, "ModelDisposeCanceled"),
        }
    }
}

#[derive(Debug, Deserialize, Serialize, sqlx::Type)]
pub enum TaskInspectionStatus {
    Resolve,
    Reject,
}

impl fmt::Display for TaskInspectionStatus {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            TaskInspectionStatus::Resolve => write!(f, "Resolve"),
            TaskInspectionStatus::Reject => write!(f, "Reject"),
        }
    }
}

#[derive(Debug, Deserialize, Serialize, sqlx::FromRow)]
pub struct Task {
    pub task_id: String,                                     // 任务编号
    pub task_name: String,                                   // 任务名称
    pub task_time: String,                                   // 任务时间
    pub data_size: i64,                                      // 数据大小
    pub status: String,                                      // 任务状态
    pub progress: f32,                                       // 任务进度
    pub submit_time: Option<String>,                         // 提交时间
    pub archive_projects: Option<Json<Option<Vec<String>>>>, // 归档项目
    pub inspection_status: Option<String>,                   // 检验状态
    pub inspection_pass_time: Option<String>,                // 检验通过时间
}

impl Task {
    pub fn default(task_name: &str, data_size: &i64) -> Task {
        Task {
            task_id: uuid::Uuid::new_v4().to_string(),
            task_name: task_name.to_string(),
            task_time: chrono::Local::now().to_string(),
            data_size: data_size.clone(),
            status: TaskStatus::DataPending.to_string(),
            progress: 0.0,
            submit_time: None,
            archive_projects: None,
            inspection_status: None,
            inspection_pass_time: None,
        }
    }
}
